package com.spukmk3me.animatorpack.pack0;

import com.spukmk3me.scene.Animator;
import com.spukmk3me.scene.Node;

/**
 *  An animator used for translating scene node.
 */
public final class TranslateAnimator extends Animator
{
    public TranslateAnimator()
    {
        m_animating = false;
    }      

    public void animate( int deltaTime )
    {
        if ( !m_animating )
            return;
        
        if ( m_relayTime > 0 )
        {
            m_relayTime -= deltaTime;
            
            if ( m_relayTime > 0 )
                return;
            else
                deltaTime = -m_relayTime;
        }
        
        float deltaTimef = (float)deltaTime / 0x00010000;
        
        m_currentX += m_speedX * deltaTimef;
        m_currentY += m_speedY * deltaTimef;

        if ( m_speedX > 0 )
        {
            if ( m_currentX > m_desX )
                m_currentX = m_desX;
        }
        else
        {
            if ( m_currentX < m_desX )
                m_currentX = m_desX;
        }

        if ( m_speedY > 0 )
        {
            if ( m_currentY > m_desY )
                m_currentY = m_desY;
        }
        else
        {
            if ( m_currentY < m_desY )
                m_currentY = m_desY;
        }
        
        getNode().reset();
        getNode().setTrans( m_currentX, m_currentY );
        

        if ( (m_currentX == m_desX) && (m_currentY == m_desY) )
            m_animating = false;
    }

    /**
     *  Setup the translate information.
     *  \details Do nothing if the node is null.
     *  @param speed The speed of moving.
     *  @param desX The X-coordinate of destination.
     *  @param desY The Y-coordinate of destination.
     */
    public void setAnimating( float speed,
        float srcX, float srcY, float srcZ,
        float desX, float desY, float desZ, int relayTime )
    {
        m_relayTime = relayTime;
        m_currentX  = srcX;
        m_currentY  = srcY;
        m_desX      = desX;
        m_desY      = desY;

        float deltaX  = m_desX - m_currentX;
        float deltaY  = m_desY - m_currentY;
        
        if ( (deltaX != 0) || (deltaY != 0) )
        {            
            float rangeSpeed = (float)(speed / Math.sqrt( deltaX * deltaX + deltaY * deltaY ));

            m_speedX = rangeSpeed * deltaX;
            m_speedY = rangeSpeed * deltaY;
            m_animating = true;
        }
        else
        {
            m_speedX = m_speedY = 0f;
            m_animating = false;
        }

        //System.out.println( "Speed: " + m_speedX + ' ' + m_speedY );
    }

    /**
     *  @return True if and only if the node hasn't reached the destination,
     * even it's still at relay period.
     */
    public final boolean isAnimating()
    {
        if ( getNode() == null )
            return false;
        
        return m_animating;
    }
    
    @Override
    protected void onNodePrepareToChange( Node newNode ) {}
    
    @Override
    protected void onNodeChanged() {}    

    private int     m_relayTime;
    private float   m_currentX, m_currentY, m_speedX, m_speedY, m_desX, m_desY;
    private boolean m_animating;
}
